<template>
  <div
    ref="boxRef"
    class="moveable-box"
    :style="{
      position: 'absolute',
      left: x + 'px',
      top: y + 'px',
      width: width + 'px',
      height: height + 'px',
      transform: `rotate(${rotate}deg)`,
      zIndex: zIndex || 1,
      ...boxStyle
    }"
  >
    <slot />
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, watch } from 'vue'
import Moveable from 'moveable'

const props = withDefaults(defineProps<{
  id?: number,
  x?: number,
  y?: number,
  width?: number,
  height?: number,
  rotate?: number,
  canvasScale?: number,
  canvasOffset?: { x: number, y: number },
  zIndex?: number,
  boxStyle?: Record<string, any>,
  active?: boolean,
  hideHandles?: boolean
}>(), {
  x: 0,
  y: 0,
  width: 0,
  height: 0,
  rotate: 0,
  canvasScale: 1,
  canvasOffset: () => ({ x: 0, y: 0 }),
  zIndex: 1,
  boxStyle: () => ({}),
  active: false,
  hideHandles: false
})

const emit = defineEmits(['update', 'dragEnd'])

const boxRef = ref<HTMLElement | null>(null)
let moveable: Moveable | null = null

function updateMoveable() {
  if (moveable && boxRef.value) moveable.updateRect()
}

function createMoveable() {
  if (moveable || !boxRef.value) return
  moveable = new Moveable(document.body, {
    target: boxRef.value,
    draggable: true,
    resizable: true,
    rotatable: true,
    zoom: 1, // 固定为1，缩放由父容器处理
    origin: false,
    keepRatio: false,
    snappable: false,
    elementGuidelines: [],
  })
  moveable.on('drag', ({ left, top }) => {
    emit('update', {
      id: props.id!,
      x: left,
      y: top,
      width: props.width!,
      height: props.height!,
      rotate: props.rotate || 0,
    })
  })
  moveable.on('resize', ({ width, height, drag }) => {
    emit('update', {
      id: props.id!,
      x: drag.left,
      y: drag.top,
      width: width,
      height: height,
      rotate: props.rotate || 0,
    })
  })
  moveable.on('dragEnd', () => emit('dragEnd'))
  moveable.on('resizeEnd', () => emit('dragEnd'))
}

const toggleHandles = () => {
  if(moveable){
    if (props.active && !props.hideHandles) {
      moveable.renderDirections = ["n", "ne", "e", "se", "s", "sw", "w", "nw"];
      moveable.rotationPosition = "top";
    } else {
      moveable.renderDirections = [];
      moveable.rotationPosition = "none";
    }
  }
};

watch(() => props.active, (val) => {
  if (moveable) {
    // moveable.draggable = val
    // moveable.resizable = val
    // moveable.rotatable = val
    toggleHandles();
    updateMoveable()
  }
}, { immediate: true })

watch(() => props.hideHandles, () => {
  if (moveable) {
    toggleHandles();
    updateMoveable()
  }
}, { immediate: true })

watch(() => [props.x, props.y, props.width, props.height, props.rotate], updateMoveable)

onMounted(() => {
  createMoveable()
  toggleHandles()
  updateMoveable()
})
onBeforeUnmount(() => {
  if (moveable) {
    moveable.destroy()
    moveable = null
  }
})
</script>

<style scoped>
.moveable-box {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
  border: none;
}
</style> 